package org.EasyDevelop.Builder;

import org.EasyDevelop.Bean.Constants;
import org.EasyDevelop.Bean.FieldInfo;
import org.EasyDevelop.Bean.TableInfo;
import org.EasyDevelop.Utils.DateUtils;
import org.EasyDevelop.Utils.StringUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.List;
import java.util.Map;

public class MapperBuilder {
    private static Logger logger = LoggerFactory.getLogger(MapperBuilder.class);

    public static void execute(TableInfo tableInfo){
        File folder = new File(Constants.PATH_MAPPER);

        if(!folder.exists()) folder.mkdirs();

        File poFile = new File(folder, tableInfo.getBeanName() + StringUtils.upperCaseFirstLetter(Constants.SUFFIX_MAP.get("mappers")) + Constants.JAVA_SUFFIX);

        OutputStream os = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;

        try {
            os = new FileOutputStream(poFile);
            osw = new OutputStreamWriter(os, "UTF8");
            bw = new BufferedWriter(osw);

            //package
            bw.write("package " + Constants.PACKAGE_MAPPER + ";");
            bw.newLine();
            bw.newLine();

            bw.write("import " + Constants.PACKAGE_MAPPER + ".BaseMapper;");
            bw.newLine();

            //import

            //@Param
            bw.write("import org.apache.ibatis.annotations.Param;");
            bw.newLine();
            bw.write("import org.apache.ibatis.annotations.Mapper;");
            bw.newLine();

            //class comment
            CommentBuilder.createClassComment(bw,tableInfo.getComment() + " Mapper接口");
            //class start
            bw.write("@Mapper");
            bw.newLine();
            bw.write("public interface " + tableInfo.getBeanName() + StringUtils.upperCaseFirstLetter(Constants.SUFFIX_MAP.get("mappers")) + "<T,P> extends BaseMapper {");
            bw.newLine();

            //index Collections
            Map<String, List<FieldInfo>> keyIndexMap = tableInfo.getKeyIndexMap();

            StringBuilder methodName = new StringBuilder();
            StringBuilder methodParams = new StringBuilder();
            //method
            for (Map.Entry<String, List<FieldInfo>> entry : keyIndexMap.entrySet()) {
                List<FieldInfo> keyFieldList = entry.getValue();

                //叠加索引相关值
                Integer idx = 0;
                for (FieldInfo fieldInfo : keyFieldList) {
                    methodName.append(StringUtils.upperCaseFirstLetter(fieldInfo.getPropertyName()));
                    methodParams.append(
                            "@Param(\"" + fieldInfo.getPropertyName() + "\") " +
                            fieldInfo.getJavaType() + " " +
                            StringUtils.lowerCaseFirstLetter(fieldInfo.getPropertyName())
                    );
                    if(idx++<keyFieldList.size()-1){
                        methodName.append("And");
                        methodParams.append(", ");
                    }
                }

                //select
                CommentBuilder.createMethodComment(bw,"根据" + methodName + "查询");
                bw.write("\tT selectBy" + methodName.toString());
                bw.write("(");
                bw.write(methodParams.toString());
                bw.write(");");
                bw.newLine();

                //update
                CommentBuilder.createMethodComment(bw,"根据" + methodName + "更新");
                bw.write("\tLong updateBy" + methodName.toString());
                bw.write("(");
                bw.write("@Param(\"bean\") T t, ");
                bw.write(methodParams.toString());
                bw.write(");");
                bw.newLine();

                //delete
                CommentBuilder.createMethodComment(bw,"根据" + methodName + "删除");
                bw.write("\tLong deleteBy" + methodName.toString());
                bw.write("(");
                bw.write(methodParams.toString());
                bw.write(");");
                bw.newLine();


                methodName = new StringBuilder();
                methodParams = new StringBuilder();
            }

            bw.write("}");
            bw.flush();

        } catch (Exception e) {
            logger.error("创建Mapper失败,{}",e);
        } finally {
            if(bw!=null)
                try{
                    bw.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            if(osw!=null)
                try{
                    osw.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            if(os!=null)
                try{
                    os.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
        }

    }
}
